from PyQt5.QtWidgets import (
    QWidget, QVBoxLayout, QHBoxLayout, QPushButton,
    QTableWidget, QTableWidgetItem, QHeaderView,
    QLabel, QComboBox, QDateEdit, QGroupBox,
    QMessageBox, QLineEdit, QGridLayout, QCheckBox
)
from PyQt5.QtGui import QColor
from PyQt5.QtCore import Qt, QDate
import datetime
import logging
import re

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


class TransactionTab(QWidget):
    def __init__(self, db):
        super().__init__()
        self.db = db
        self.initUI()
        self.load_initial_data()

    def initUI(self):
        main_layout = QVBoxLayout()

        # 筛选功能区
        filter_group = QGroupBox("交易筛选")
        filter_layout = QGridLayout()

        # 查询模式选择
        filter_layout.addWidget(QLabel("查询模式:"), 0, 0)
        self.search_mode = QComboBox()
        self.search_mode.addItems(["精确查询", "模糊查询"])
        self.search_mode.setCurrentIndex(0)
        filter_layout.addWidget(self.search_mode, 0, 1)

        # 查询类型选择
        filter_layout.addWidget(QLabel("查询类型:"), 1, 0)
        self.filter_type = QComboBox()
        self.filter_type.addItems([
            "所有交易",
            "卡号(cardID)",
            "交易ID(tradeID)",
            "客户姓名(customerName)",
            "交易类型(tradeType)"
        ])
        self.filter_type.setCurrentIndex(0)
        filter_layout.addWidget(self.filter_type, 1, 1)

        # 查询值输入框
        self.filter_value_container = QGroupBox("查询条件")
        self.filter_value_container.setCheckable(True)
        self.filter_value_container.setChecked(False)

        value_layout = QVBoxLayout()
        self.filter_value = QLineEdit()
        self.filter_value.setPlaceholderText("请输入查询值")
        value_layout.addWidget(self.filter_value)
        self.filter_value_container.setLayout(value_layout)
        filter_layout.addWidget(self.filter_value_container, 2, 0, 1, 2)

        # 日期范围容器
        self.date_container = QGroupBox("日期范围")
        self.date_container.setCheckable(True)
        self.date_container.setChecked(False)

        date_layout = QHBoxLayout()
        self.date_start = QDateEdit(QDate.currentDate().addMonths(-1))
        self.date_start.setCalendarPopup(True)
        self.date_start.setDisplayFormat("yyyy/MM/dd")
        self.date_end = QDateEdit(QDate.currentDate())
        self.date_end.setCalendarPopup(True)
        self.date_end.setDisplayFormat("yyyy/MM/dd")
        date_layout.addWidget(self.date_start)
        date_layout.addWidget(QLabel("至"))
        date_layout.addWidget(self.date_end)
        self.date_container.setLayout(date_layout)
        filter_layout.addWidget(self.date_container, 3, 0, 1, 2)

        # 交易类型选择
        self.type_container = QGroupBox("交易类型")
        self.type_container.setCheckable(True)
        self.type_container.setChecked(False)

        type_layout = QHBoxLayout()
        self.type_combo = QComboBox()
        self.type_combo.addItems(["所有类型", "存入", "支取", "转账", "冲正"])
        type_layout.addWidget(self.type_combo)
        self.type_container.setLayout(type_layout)
        filter_layout.addWidget(self.type_container, 4, 0, 1, 2)

        # 筛选按钮
        filter_btn = QPushButton("筛选")
        filter_btn.clicked.connect(self.filter_transactions)
        filter_btn.setMinimumHeight(40)
        filter_layout.addWidget(filter_btn, 5, 0, 1, 2)

        # 连接信号
        self.filter_type.currentIndexChanged.connect(self.update_query_fields)
        self.date_container.toggled.connect(self.update_query_fields)
        self.type_container.toggled.connect(self.update_query_fields)
        self.filter_value_container.toggled.connect(self.update_query_fields)

        filter_group.setLayout(filter_layout)
        main_layout.addWidget(filter_group)

        # 交易表格
        self.table = QTableWidget()
        self.table.setColumnCount(6)
        self.table.setHorizontalHeaderLabels([
            "交易ID", "卡号", "交易时间",
            "类型", "金额", "备注"
        ])

        # 设置表格属性
        self.table.setSortingEnabled(True)
        self.table.setSelectionBehavior(QTableWidget.SelectRows)
        self.table.setSelectionMode(QTableWidget.SingleSelection)

        # 设置列宽策略
        header = self.table.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.ResizeToContents)  # 交易ID
        header.setSectionResizeMode(1, QHeaderView.Stretch)  # 卡号
        header.setSectionResizeMode(2, QHeaderView.ResizeToContents)  # 交易时间
        header.setSectionResizeMode(3, QHeaderView.ResizeToContents)  # 类型
        header.setSectionResizeMode(4, QHeaderView.ResizeToContents)  # 金额
        header.setSectionResizeMode(5, QHeaderView.Stretch)  # 备注

        main_layout.addWidget(self.table)

        # 操作按钮
        btn_layout = QHBoxLayout()
        reverse_btn = QPushButton("冲正交易")
        reverse_btn.clicked.connect(self.reverse_transaction)
        reverse_btn.setMinimumHeight(40)
        btn_layout.addWidget(reverse_btn)

        refresh_btn = QPushButton("刷新列表")
        refresh_btn.clicked.connect(self.load_initial_data)
        refresh_btn.setMinimumHeight(40)
        btn_layout.addWidget(refresh_btn)

        main_layout.addLayout(btn_layout)
        self.setLayout(main_layout)

        # 初始化字段状态
        self.update_query_fields()

    def update_query_fields(self):
        """根据选择的查询类型更新UI状态"""
        filter_type = self.filter_type.currentText()

        # 根据查询类型显示/隐藏组件
        if "所有交易" in filter_type:
            self.filter_value_container.setVisible(False)
            self.filter_value_container.setChecked(False)
        else:
            self.filter_value_container.setVisible(True)
            self.filter_value_container.setChecked(True)

        # 日期范围总是可用
        self.date_container.setVisible(True)
        self.type_container.setVisible(True)

    def load_initial_data(self):
        """初始加载所有交易数据"""
        try:
            # 基本查询
            query = """
            SELECT 
                t.tradeID, 
                t.cardID, 
                t.tradeDate,
                t.tradeType,
                t.tradeMoney,
                t.remark,
                c.customerID,
                u.customerName
            FROM tradeinfo t
            JOIN cardinfo c ON t.cardID = c.cardID
            JOIN userinfo u ON c.customerID = u.customerID
            ORDER BY t.tradeDate DESC
            """

            results = self.db.execute_query(query)
            self.display_transactions(results)

        except Exception as e:
            logger.error(f"初始数据加载失败: {str(e)}")
            QMessageBox.critical(self, "加载失败", f"加载交易数据时出错: {str(e)}")

    def filter_transactions(self):
        """应用筛选条件查询交易"""
        try:
            # 构建基础查询
            base_query = """
            SELECT 
                t.tradeID, 
                t.cardID, 
                t.tradeDate,
                t.tradeType,
                t.tradeMoney,
                t.remark,
                c.customerID,
                u.customerName
            FROM tradeinfo t
            JOIN cardinfo c ON t.cardID = c.cardID
            JOIN userinfo u ON c.customerID = u.customerID
            """

            where_clauses = []
            params = []

            # 1. 处理主查询条件
            filter_type = self.filter_type.currentText()
            search_mode = self.search_mode.currentText()
            filter_value = self.filter_value.text().strip()

            if "所有交易" not in filter_type and filter_value:
                if "卡号" in filter_type:
                    if search_mode == "精确查询":
                        where_clauses.append("t.cardID = %s")
                    else:
                        where_clauses.append("t.cardID LIKE %s")
                        filter_value = f"%{filter_value}%"
                    params.append(filter_value)

                elif "交易ID" in filter_type:
                    if search_mode == "精确查询":
                        where_clauses.append("t.tradeID = %s")
                    else:
                        where_clauses.append("CAST(t.tradeID AS CHAR) LIKE %s")
                        filter_value = f"%{filter_value}%"
                    params.append(filter_value)

                elif "客户姓名" in filter_type:
                    if search_mode == "精确查询":
                        where_clauses.append("u.customerName = %s")
                    else:
                        where_clauses.append("u.customerName LIKE %s")
                        filter_value = f"%{filter_value}%"
                    params.append(filter_value)

                elif "交易类型" in filter_type:
                    if search_mode == "精确查询":
                        where_clauses.append("t.tradeType = %s")
                    else:
                        where_clauses.append("t.tradeType LIKE %s")
                        filter_value = f"%{filter_value}%"
                    params.append(filter_value)

            # 2. 处理日期范围条件
            if self.date_container.isChecked():
                start_date = self.date_start.date().toString("yyyy-MM-dd") + " 00:00:00"
                end_date = self.date_end.date().toString("yyyy-MM-dd") + " 23:59:59"

                where_clauses.append("t.tradeDate BETWEEN %s AND %s")
                params.extend([start_date, end_date])

            # 3. 处理交易类型条件
            if self.type_container.isChecked():
                selected_type = self.type_combo.currentText()
                if "所有类型" not in selected_type:
                    where_clauses.append("t.tradeType = %s")
                    params.append(selected_type)

            # 构建完整查询
            if where_clauses:
                where_clause = "WHERE " + " AND ".join(where_clauses)
            else:
                where_clause = ""

            order_clause = "ORDER BY t.tradeDate DESC"
            query = f"{base_query} {where_clause} {order_clause}"

            # 执行查询
            logger.info(f"执行查询: {query} with params {params}")
            results = self.db.execute_query(query, params)

            if not results:
                QMessageBox.information(self, "无结果", "没有找到匹配的交易记录")

            self.display_transactions(results)

        except Exception as e:
            logger.error(f"筛选交易失败: {str(e)}")
            QMessageBox.critical(self, "筛选失败", f"筛选交易数据时出错: {str(e)}")

    def display_transactions(self, results):
        """显示交易数据到表格"""
        try:
            # 确保有交易ID列
            self.table.setRowCount(0)
            if not results:
                self.table.setRowCount(1)
                self.table.setItem(0, 0, QTableWidgetItem("没有找到交易数据"))
                return

            self.table.setRowCount(len(results))
            for row_idx, row in enumerate(results):
                # 确保行数据包含需要的键
                required_keys = ['tradeID', 'cardID', 'tradeDate', 'tradeType', 'tradeMoney', 'remark']
                for key in required_keys:
                    if key not in row:
                        logger.error(f"交易数据缺少字段: {key}")
                        row[key] = "N/A"  # 防止后续访问失败

                # 格式化日期时间
                trade_date = row['tradeDate']
                if isinstance(trade_date, datetime.datetime):
                    date_str = trade_date.strftime("%Y-%m-%d %H:%M:%S")
                else:
                    date_str = str(trade_date)

                # 交易ID
                self.table.setItem(row_idx, 0, QTableWidgetItem(str(row['tradeID'])))

                # 卡号
                card_id = row['cardID']
                card_item = QTableWidgetItem(card_id)
                self.table.setItem(row_idx, 1, card_item)

                # 交易时间
                time_item = QTableWidgetItem(date_str)
                time_item.setTextAlignment(Qt.AlignCenter)
                self.table.setItem(row_idx, 2, time_item)

                # 交易类型（带颜色）
                trade_type = str(row['tradeType'])
                type_item = QTableWidgetItem(trade_type)
                type_item.setTextAlignment(Qt.AlignCenter)

                if "存入" in trade_type:
                    type_item.setBackground(QColor(200, 255, 200))  # 浅绿色
                elif any(x in trade_type for x in ["支取", "转出"]):
                    type_item.setBackground(QColor(255, 200, 200))  # 浅红色
                elif "转账" in trade_type:
                    type_item.setBackground(QColor(200, 200, 255))  # 浅蓝色
                elif "冲正" in trade_type:
                    type_item.setBackground(QColor(255, 220, 150))  # 浅橙色

                self.table.setItem(row_idx, 3, type_item)

                # 金额（右对齐）
                try:
                    amount = float(row['tradeMoney'])
                    formatted_amount = f"{amount:.2f}"
                except (TypeError, ValueError):
                    formatted_amount = "0.00"

                amount_item = QTableWidgetItem(formatted_amount)
                amount_item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
                self.table.setItem(row_idx, 4, amount_item)

                # 备注（处理空值）
                remark = str(row['remark']) if row['remark'] else ""
                self.table.setItem(row_idx, 5, QTableWidgetItem(remark))

            # 调整列宽
            self.table.resizeColumnsToContents()

        except Exception as e:
            logger.exception("显示交易数据失败")
            QMessageBox.critical(self, "显示错误", f"显示交易数据时出错: {str(e)}")

    def reverse_transaction(self):
        """冲正交易操作"""
        selected_row = self.table.currentRow()
        if selected_row < 0:
            QMessageBox.warning(self, "冲正", "请先选择一笔交易")
            return

        try:
            trade_id = int(self.table.item(selected_row, 0).text())
            trade_type = self.table.item(selected_row, 3).text()
            amount = float(self.table.item(selected_row, 4).text())
            card_id = self.table.item(selected_row, 1).text()
            original_remark = self.table.item(selected_row, 5).text()

            # 确认冲正对话框
            confirmation = QMessageBox.question(
                self, "确认冲正",
                f"确定要冲正该交易吗?\n交易ID: {trade_id}\n类型: {trade_type}\n金额: {amount:.2f}\n\n原备注: {original_remark}",
                QMessageBox.Yes | QMessageBox.No
            )

            if confirmation == QMessageBox.No:
                return

            # 确定冲正类型
            reverse_map = {
                "存入": "冲正存入",
                "支取": "冲正支取",
                "转账": "冲正转账",
                "转账出": "冲正转账",
                "冲正存入": "重复冲正",
                "冲正支取": "重复冲正",
                "冲正转账": "重复冲正"
            }

            new_type = reverse_map.get(trade_type, "冲正操作")
            reverse_amount = -amount

            # 执行冲正操作
            new_remark = f"[冲正] {original_remark}" if original_remark else "交易冲正"

            insert_query = """
            INSERT INTO tradeinfo 
                (cardID, tradeDate, tradeType, tradeMoney, remark) 
            VALUES 
                (%s, NOW(), %s, %s, %s)
            """
            self.db.execute_query(
                insert_query,
                (card_id, new_type, reverse_amount, new_remark),
                commit=True
            )

            # 在原交易添加冲正标记
            update_query = """
            UPDATE tradeinfo 
            SET remark = CONCAT(IFNULL(remark, ''), %s) 
            WHERE tradeID = %s
            """
            self.db.execute_query(
                update_query,
                (f"; [已冲正于 {datetime.datetime.now().strftime('%Y-%m-%d %H:%M')}]", trade_id),
                commit=True
            )

            # 刷新数据
            self.filter_transactions()
            QMessageBox.information(self, "冲正成功", f"交易 {trade_id} 已成功冲正")

        except ValueError:
            QMessageBox.critical(self, "数据错误", "交易金额格式无效")
        except Exception as e:
            logger.exception("冲正交易失败")
            QMessageBox.critical(self, "操作失败", f"冲正操作出错: {str(e)}")